package com.chensi.admin.shop.service.impl;

import com.chensi.admin.shop.common.BaseErrorCode;
import com.chensi.admin.shop.domain.CompanyItem;
import com.chensi.admin.shop.dto.mapper.CompanyItemMapper;
import com.chensi.admin.shop.service.CompanyItemService;
import com.chensi.admin.shop.util.BeanUtils;
import com.chensi.admin.shop.util.SpecificationUtil;
import com.chensi.admin.shop.dao.CompanyItemRepository;
import com.chensi.admin.shop.dto.CompanyItemDTO;
import com.chensi.admin.shop.exception.BaseException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author si.chen
 * @date 2019/7/19 8:59
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class CompanyItemServiceImpl implements CompanyItemService {

    private final CompanyItemRepository companyItemRepository;

    private final CompanyItemMapper companyItemMapper;

    @Autowired
    public CompanyItemServiceImpl(CompanyItemRepository companyItemRepository, CompanyItemMapper companyItemMapper) {
        this.companyItemRepository = companyItemRepository;
        this.companyItemMapper = companyItemMapper;
    }

    @Override
    public List<CompanyItemDTO> list(CompanyItem entity) throws BaseException {
        Sort sort = new Sort(Sort.Direction.ASC, "id");
        return companyItemRepository.findAll(this.getSpecification(entity), sort).stream().map(companyItemMapper::toDTO)
                .collect(Collectors.toList());
    }

    @Override
    public CompanyItem get(String id) throws BaseException {
        Optional<CompanyItem> optional = companyItemRepository.findById(id);
        return optional.orElseThrow(() -> new BaseException(BaseErrorCode.ITEM_NOT_FOUND));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(CompanyItem entity) throws BaseException {
        companyItemRepository.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(CompanyItem companyItem) throws BaseException {
        CompanyItem entity = this.get(companyItem.getId());
        BeanUtils.copyNotNullProperties(companyItem, entity);
        companyItemRepository.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) throws BaseException {
        companyItemRepository.deleteById(id);
    }

    @SuppressWarnings("Duplicates")
    private Specification<CompanyItem> getSpecification(CompanyItem entity) {
        return (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            SpecificationUtil.baseSpecification(root, cb, list, entity);
            if (StringUtils.isNotBlank(entity.getName())) {
                Predicate predicate = cb.equal(root.get("name"), entity.getName().trim());
                list.add(predicate);
            }
            if (entity.getCompany() != null && StringUtils.isNotBlank(entity.getCompany().getId())) {
                Predicate predicate = cb.equal(root.get("company").get("id"), entity.getCompany().getId().trim());
                list.add(predicate);
            }
            query.where(list.toArray(new Predicate[0]));
            return query.getRestriction();
        };
    }
}
